/*
 *	Yalala
 *	
 *	Copyright © MediaMonks B.V.
 *	All rights reserved.
 *	
 *	Redistribution and use in source and binary forms, with or without
 *	modification, are permitted provided that the following conditions are met:
 *	1. Redistributions of source code must retain the above copyright
 *	   notice, this list of conditions and the following disclaimer.
 *	2. Redistributions in binary form must reproduce the above copyright
 *	   notice, this list of conditions and the following disclaimer in the
 *	   documentation and/or other materials provided with the distribution.
 *	3. All advertising materials mentioning features or use of this software
 *	   must display the following acknowledgement:
 *	   This product includes software developed by MediaMonks B.V.
 *	4. Neither the name of MediaMonks B.V. nor the
 *	   names of its contributors may be used to endorse or promote products
 *	   derived from this software without specific prior written permission.
 *	
 *	THIS SOFTWARE IS PROVIDED BY MEDIAMONKS B.V. ''AS IS'' AND ANY
 *	EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *	WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *	DISCLAIMED. IN NO EVENT SHALL MEDIAMONKS B.V. BE LIABLE FOR ANY
 *	DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *	ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *	(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *	
 */

package com.mediamonks.yalala.ui.connections 
{
	import temple.codecomponents.scroll.CodeScrollBar;
	import temple.common.enum.Direction;
	import temple.common.enum.Orientation;
	import temple.common.interfaces.IHasValue;
	import temple.core.display.CoreSprite;
	import temple.data.collections.HashMap;
	import temple.ui.form.components.MultiElementComponent;
	import temple.ui.layout.LayoutBehavior;
	import temple.ui.layout.liquid.LiquidBehavior;
	import temple.ui.scroll.ScrollBehavior;
	import temple.ui.tooltip.ToolTip;
	import temple.utils.keys.KeyCode;
	import temple.utils.keys.KeyManager;

	import flash.events.Event;
	import flash.geom.Rectangle;

	/**
	 * @author Thijs Broerse
	 */
	public class Connections extends MultiElementComponent implements IHasValue
	{
		private static const _PREFIX:String = "c";
		
		private var _content:CoreSprite;
		private var _buttons:HashMap;
		private var _allButton:ConnectionButton;
		private var _scrollBehavior:ScrollBehavior;

		public function Connections()
		{
			this._content = new CoreSprite();
			this.addChild(this._content);
			new LayoutBehavior(this._content, Orientation.HORIZONTAL, Direction.ASCENDING, 4);
			
			this._buttons = new HashMap("Connection Buttons");
			this._allButton = this.addConnection(0, "All");
			this._allButton.selected = true;
			
			if (this.stage) KeyManager.init(this.stage);
			
			new LiquidBehavior(this, {left:20, right: 0});
			
			this._scrollBehavior = new ScrollBehavior(this._content, new Rectangle(0, 0, 300, 20));
			
			var scrollBar:CodeScrollBar = new CodeScrollBar(Orientation.HORIZONTAL, 160, true, this._scrollBehavior);
			
			this.addChild(scrollBar);
			scrollBar.left = 0;
			scrollBar.right = 0;
			scrollBar.bottom = -scrollBar.height;
			
			ToolTip.add(this, "Filter by connection. \nUse 'Ctrl' or 'Shift' keys while pressing to select multiple connections.");
		}
		
		override public function get width():Number 
		{
			return this._scrollBehavior.width;
		}

		override public function set width(value:Number):void 
		{
			this._scrollBehavior.width = value;
		}

		public function get contentWidth():Number 
		{
			return this._scrollBehavior.contentWidth;
		}

		override public function get height():Number 
		{
			return this._scrollBehavior.height;
		}

		override public function set height(value:Number):void 
		{
			this._scrollBehavior.height = value;
		}

		public function addConnection(id:Number, name:String):ConnectionButton 
		{
			if (isNaN(id)) return null;
			
			if (!this._buttons[_PREFIX + id])
			{
				var button:ConnectionButton = new ConnectionButton(id, name);
				button.addEventListener(Event.CHANGE, this.handleButtonChange);
				this._content.addChild(button);
				this.addElement(button);
				
				this._buttons[_PREFIX + id] = button;
				
				this._content.dispatchEvent(new Event(Event.RESIZE));
				this.dispatchEvent(new Event(Event.RESIZE));
			}
			else if (name)
			{
				ConnectionButton(this._buttons[_PREFIX + id]).name = name;
			}
			return ConnectionButton(this._buttons[_PREFIX + id]);
		}

		override public function get value():*
		{
			var value:Array = [];
			
			// deselect other buttons
			for each (var button : ConnectionButton in this._buttons) 
			{
				if (button.selected) value.push(button.value);
			}
			return value;
		}

		public function clear():void 
		{
			for (var id : String in this._buttons)
			{
				if (ConnectionButton(this._buttons[id]) != this._allButton)
				{
					this.removeElement(this._buttons[id]);
					ConnectionButton(this._buttons[id]).destruct();
					delete this._buttons[id];
				}
			}
		}
		
		public function clearConnection(id:Number):void 
		{
			if (ConnectionButton(this._buttons[_PREFIX + id]).selected)
			{
				this._allButton.selected = true;
			}
			
			ConnectionButton(this._buttons[_PREFIX + id]).destruct();
			delete this._buttons[_PREFIX + id];
		}

		private function handleButtonChange(event:Event):void 
		{
			var target:ConnectionButton = ConnectionButton(event.target);
			
			if (target.selected && !(KeyManager.isDown(KeyCode.SHIFT) || KeyManager.isDown(KeyCode.CONTROL)))
			{
				// deselect other buttons
				for each (var button : ConnectionButton in this._buttons) 
				{
					if (button != target && button.selected) button.selected = false;
				}
			}
			else if (!target.selected)
			{
				// check if there is a button selected, otherwise select the allButton
				var selected:Boolean;
				for each (button in this._buttons) 
				{
					if (button.selected)
					{
						selected = true;
						break;
					}
				}
				if (!selected) this._allButton.selected = true;
			}
			this.dispatchEvent(event.clone());
		}
	}
}
